package com.etone.smartAudit.utils.word;

import lombok.extern.log4j.Log4j2;
import org.apache.poi.xwpf.usermodel.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author: sovy
 * @date: 2021/2/2
 * @description:
 */
@Log4j2
public class ForeignWordUtil {
    private XWPFDocument xwpfDocument;

    private Map<String, Object> datas;

    public ForeignWordUtil(XWPFDocument xwpfDocument, Map<String, Object> datas) {
        this.xwpfDocument = xwpfDocument;
        this.datas = datas;
    }

    public XWPFDocument create() {
        List<String> keys = parseParagraphKey();
        List<String> removeKeys = keys.stream().filter(key -> !datas.keySet().contains(key)).collect(Collectors.toList());
        //移除菜单
        remove(removeKeys);
        replaceParams();
        return xwpfDocument;
    }

    public void replaceParams() {
        List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
        List<XWPFTable> tables = xwpfDocument.getTables();

        String regex = "\\$\\{(.*?)}";
        Pattern pattern = Pattern.compile(regex);

        log.info("------------------paragraph------------------");
        //替换段落内容
        for (XWPFParagraph paragraph : paragraphs) {
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                String text = run.text();
                run.setText(replaceText(pattern, text), 0);
            }
        }
        log.info("------------------table------------------");
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> tableCells = row.getTableCells();
                for (XWPFTableCell tableCell : tableCells) {
                    List<XWPFParagraph> cellParagraphs = tableCell.getParagraphs();
                    for (XWPFParagraph cellParagraph : cellParagraphs) {
                        List<XWPFRun> runs = cellParagraph.getRuns();
                        for (XWPFRun run : runs) {
                            String text = run.text();
                            run.setText(replaceText(pattern, text), 0);
                        }
                    }
                }
            }
        }

    }

    public String replaceText(Pattern pattern, String text) {

        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            String group = matcher.group(1);
            if (datas.containsKey(group)) {

                String replaceValue = String.valueOf(datas.get(group));
                text = text.replaceAll("\\$\\{" + group + "\\}", replaceValue);
            } else {
                continue;
            }
            matcher.reset(text);
        }

        return text;
    }

    public List<String> parseParagraphKey() {
        String regex = "^<!--(.+)-->$";
        Pattern pattern = Pattern.compile(regex);
        List<String> keys = new ArrayList<>();
        List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            String text = paragraph.getText();
            Matcher matcher = pattern.matcher(text);
            if (matcher.find()) {
                String key = matcher.group(1);
                if (!keys.contains(key)) {
                    keys.add(key);
                }

            }
        }
        return keys;
    }


    public void remove(List<String> keys) {
        for (String key : keys) {
            remove(key);
        }
        List<XWPFParagraph> removeElements = new ArrayList<>();
        String regex = "^<!--(.+)-->$";
        Pattern pattern = Pattern.compile(regex);
        for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) {
            String text = paragraph.getText();
            Matcher matcher = pattern.matcher(text);
            if (matcher.find()) {
                removeElements.add(paragraph);
            }
        }
        for (XWPFParagraph removeElement : removeElements) {
            xwpfDocument.removeBodyElement(xwpfDocument.getPosOfParagraph(removeElement));
        }
    }

    public void remove(String key) {

        List<IBodyElement> removeElements = new ArrayList<>();
        List<IBodyElement> bodyElements = xwpfDocument.getBodyElements();
        boolean isDelete = false;
        for (IBodyElement bodyElement : bodyElements) {
            switch (bodyElement.getElementType()) {
                case PARAGRAPH:
                    XWPFParagraph xwpfParagraph = (XWPFParagraph) bodyElement;
                    String text = xwpfParagraph.getText();
                    if (text.contains("<!--" + key + "-->")) {
                        isDelete = !isDelete;
                    }
                    break;
            }
            if (isDelete) {
                removeElements.add(bodyElement);
            }
        }

        removeElements = removeElements.stream().distinct().collect(Collectors.toList());
        for (IBodyElement bodyElement : removeElements) {
            switch (bodyElement.getElementType()) {
                case PARAGRAPH:
                    XWPFParagraph xwpfParagraph = (XWPFParagraph) bodyElement;
                    xwpfDocument.removeBodyElement(xwpfDocument.getPosOfParagraph(xwpfParagraph));
                    break;
                case TABLE:
                    XWPFTable table = (XWPFTable) bodyElement;
                    xwpfDocument.removeBodyElement(xwpfDocument.getPosOfTable(table));
                    break;
            }

        }

    }
}
